import requests
import logging
from typing import Dict, Optional, List
from app.core.config import settings

logger = logging.getLogger(__name__)


class XXLJobAPI:
    """XXL-Job调度中心API客户端"""
    
    def __init__(self):
        self.admin_url = settings.XXL_JOB_ADMIN_URL.rstrip('/')
        self.username = settings.XXL_JOB_USERNAME
        self.password = settings.XXL_JOB_PASSWORD
        self.session = requests.Session()
        self.login_cookie = None
    
    def login(self) -> bool:
        """登录XXL-Job调度中心"""
        try:
            login_url = f"{self.admin_url}/login"
            
            # 先获取登录页面
            response = self.session.get(login_url)
            if response.status_code != 200:
                logger.error(f"Failed to access login page: {response.status_code}")
                return False
            
            # 提交登录表单
            login_data = {
                'userName': self.username,
                'password': self.password
            }
            
            response = self.session.post(login_url, data=login_data)
            
            # 检查是否登录成功
            if response.status_code == 200 and 'XXL_JOB_LOGIN_IDENTITY' in self.session.cookies:
                self.login_cookie = self.session.cookies.get('XXL_JOB_LOGIN_IDENTITY')
                logger.info("XXL-Job login successful")
                return True
            else:
                logger.error("XXL-Job login failed")
                return False
                
        except Exception as e:
            logger.error(f"Error during XXL-Job login: {e}")
            return False
    
    def _ensure_login(self) -> bool:
        """确保已登录"""
        if not self.login_cookie:
            return self.login()
        return True
    
    def add_job(self, job_info: Dict) -> Optional[int]:
        """添加任务"""
        if not self._ensure_login():
            return None
        
        try:
            url = f"{self.admin_url}/jobinfo/add"
            
            # 默认任务配置
            default_job = {
                'jobGroup': 1,  # 执行器ID，需要根据实际情况调整
                'jobDesc': job_info.get('jobDesc', '小红书发布任务'),
                'author': 'system',
                'scheduleType': 'CRON',
                'scheduleConf': job_info.get('scheduleConf', '0 0 12 * * ?'),  # CRON表达式
                'glueType': 'BEAN',
                'executorHandler': 'publishPostHandler',  # 对应handler中的方法名
                'executorParam': job_info.get('executorParam', ''),  # 传递给handler的参数
                'executorRouteStrategy': 'FIRST',
                'executorBlockStrategy': 'SERIAL_EXECUTION',
                'executorTimeout': 0,
                'executorFailRetryCount': 0,
                'glueRemark': 'GLUE代码初始化',
                'triggerStatus': 0  # 0-停止，1-运行
            }
            
            # 合并用户提供的配置
            default_job.update(job_info)
            
            response = self.session.post(url, data=default_job)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('code') == 200:
                    # 获取新创建的任务ID
                    job_id = result.get('content')
                    logger.info(f"Job added successfully with ID: {job_id}")
                    return job_id
                else:
                    logger.error(f"Failed to add job: {result.get('msg')}")
            else:
                logger.error(f"HTTP error when adding job: {response.status_code}")
                
        except Exception as e:
            logger.error(f"Error adding job: {e}")
        
        return None
    
    def update_job(self, job_id: int, job_info: Dict) -> bool:
        """更新任务"""
        if not self._ensure_login():
            return False
        
        try:
            url = f"{self.admin_url}/jobinfo/update"
            
            # 添加任务ID
            job_info['id'] = job_id
            
            response = self.session.post(url, data=job_info)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('code') == 200:
                    logger.info(f"Job {job_id} updated successfully")
                    return True
                else:
                    logger.error(f"Failed to update job {job_id}: {result.get('msg')}")
            else:
                logger.error(f"HTTP error when updating job {job_id}: {response.status_code}")
                
        except Exception as e:
            logger.error(f"Error updating job {job_id}: {e}")
        
        return False
    
    def start_job(self, job_id: int) -> bool:
        """启动任务"""
        if not self._ensure_login():
            return False
        
        try:
            url = f"{self.admin_url}/jobinfo/start"
            data = {'id': job_id}
            
            response = self.session.post(url, data=data)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('code') == 200:
                    logger.info(f"Job {job_id} started successfully")
                    return True
                else:
                    logger.error(f"Failed to start job {job_id}: {result.get('msg')}")
            else:
                logger.error(f"HTTP error when starting job {job_id}: {response.status_code}")
                
        except Exception as e:
            logger.error(f"Error starting job {job_id}: {e}")
        
        return False
    
    def stop_job(self, job_id: int) -> bool:
        """停止任务"""
        if not self._ensure_login():
            return False
        
        try:
            url = f"{self.admin_url}/jobinfo/stop"
            data = {'id': job_id}
            
            response = self.session.post(url, data=data)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('code') == 200:
                    logger.info(f"Job {job_id} stopped successfully")
                    return True
                else:
                    logger.error(f"Failed to stop job {job_id}: {result.get('msg')}")
            else:
                logger.error(f"HTTP error when stopping job {job_id}: {response.status_code}")
                
        except Exception as e:
            logger.error(f"Error stopping job {job_id}: {e}")
        
        return False
    
    def remove_job(self, job_id: int) -> bool:
        """删除任务"""
        if not self._ensure_login():
            return False
        
        try:
            url = f"{self.admin_url}/jobinfo/remove"
            data = {'id': job_id}
            
            response = self.session.post(url, data=data)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('code') == 200:
                    logger.info(f"Job {job_id} removed successfully")
                    return True
                else:
                    logger.error(f"Failed to remove job {job_id}: {result.get('msg')}")
            else:
                logger.error(f"HTTP error when removing job {job_id}: {response.status_code}")
                
        except Exception as e:
            logger.error(f"Error removing job {job_id}: {e}")
        
        return False
    
    def get_job_info(self, job_id: int) -> Optional[Dict]:
        """获取任务信息"""
        if not self._ensure_login():
            return None
        
        try:
            url = f"{self.admin_url}/jobinfo/pageList"
            params = {
                'jobGroup': -1,
                'triggerStatus': -1,
                'jobDesc': '',
                'executorHandler': '',
                'author': '',
                'start': 0,
                'length': 1000
            }
            
            response = self.session.get(url, params=params)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('code') == 200:
                    data = result.get('data', [])
                    for job in data:
                        if job.get('id') == job_id:
                            return job
                    logger.warning(f"Job {job_id} not found")
                else:
                    logger.error(f"Failed to get job info: {result.get('msg')}")
            else:
                logger.error(f"HTTP error when getting job info: {response.status_code}")
                
        except Exception as e:
            logger.error(f"Error getting job info for {job_id}: {e}")
        
        return None
    
    def get_job_list(self, job_group: int = -1) -> List[Dict]:
        """获取任务列表"""
        if not self._ensure_login():
            return []
        
        try:
            url = f"{self.admin_url}/jobinfo/pageList"
            params = {
                'jobGroup': job_group,
                'triggerStatus': -1,
                'jobDesc': '',
                'executorHandler': '',
                'author': '',
                'start': 0,
                'length': 1000
            }
            
            response = self.session.get(url, params=params)
            
            if response.status_code == 200:
                result = response.json()
                if result.get('code') == 200:
                    return result.get('data', [])
                else:
                    logger.error(f"Failed to get job list: {result.get('msg')}")
            else:
                logger.error(f"HTTP error when getting job list: {response.status_code}")
                
        except Exception as e:
            logger.error(f"Error getting job list: {e}")
        
        return []


# 创建全局实例
xxl_job_api = XXLJobAPI()